package com.sunday.redisson.core;

import com.sunday.common.core.lambda.ColumnMapperOperation;
import com.sunday.common.core.lambda.toolkit.support.ColumnMapper;
import com.sunday.redisson.annotation.OpenDistributedLock;
import com.sunday.redisson.lambda.toolkit.support.LockColumnMapper;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * redssion lock 字段映射
 *
 * @author zsy
 * @since 2022/10/20
 */
public class LockFieldMapping {

    private static final Map<String, Map<String, ColumnMapper>> COLUMN_CACHE_MAP = new ConcurrentHashMap<>();

    private static final ColumnMapperOperation OPERATION = new ColumnMapperOperation() {
        @Override
        public Map<String, ColumnMapper> getColumnMap(Class<?> target) {
            return COLUMN_CACHE_MAP.get(target.getName());
        }

        @Override
        public Map<String, ColumnMapper> createColumnMap(Class<?> target) {
            Map<String, ColumnMapper> map = new HashMap<>();
            Field[] fields = target.getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(OpenDistributedLock.class)) {
                    OpenDistributedLock lock = field.getAnnotation(OpenDistributedLock.class);
                    field.setAccessible(true);
                    map.put(field.getName(), LockColumnMapper.of(lock.value(), lock.errorCodeEnum(), lock.message(), field));
                }
            }
            COLUMN_CACHE_MAP.put(target.getName(), map);
            return map;
        }
    };

    public static Map<String, ColumnMapper> getColumnAdapter(Class<?> target) {
        return OPERATION.getColumnAdapter(target);
    }

}
